<?php
/**
 * Copyright 2013 Marek Kaszewski
 *
 * This file is part of the JHUB1 Online Community Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace Jhub1_Common\Entity\BO;

class EAVBO implements Extensible
{
    public static $TYPE_INTEGER = 'Integer';
    public static $TYPE_TEXT    = 'Text';
    public static $TYPE_STRING  = 'String';
    public static $TYPE_DATE    = 'Date';
    public static $TYPE_OBJECT  = 'Object';

    private $class;
    private $poInstance;
    private $eav;
    private $em;

    public function __construct($poInstance, $em)
    {
        $this->poInstance = $poInstance;
        $this->class = get_class($poInstance) . 'EAV';
        $this->em = $em;
    }

    private function persist($poInstance)
    {
        $this->em->persist($poInstance);
        $this->em->flush();
    }

    private function delete($poInstance)
    {
        $this->em->remove($poInstance);
        $this->em->flush();
    }

    private function existAttribute($name)
    {
     //   $method = 'get' . $type;
        $eavs = $this->poInstance->getEAVs();
        foreach ($eavs as $eav) {
            if ($eav->getName() == $name) {
             //   if ($eav->$method() != null) {
                    return $eav;
             //   }
            }
        }
        return null;
    }

    private function safeDelete($name, $type)
    {
        $method = 'set' . $type;
        $attribute = $this->existAttribute($name);
        $attribute->$method(null);
        $this->persist($attribute);
        $attArrs = $attribute->getArrayCopy();
        $delete = true;
        foreach ($attArrs as $key => $val) {
            if ($key != 'id' && $key != 'name') {
                if ($val != null) {
                    $delete = false;
                }
            }
        }
        if ($delete) {
            $this->delete($attribute);
        } else {
            $this->persist($attribute);
        }
    }

    private function setValue($name, $value, $type)
    {
        $method = 'set' . $type;
        $attribute = $this->existAttribute($name);
        if ($attribute != null) {
            // update
            echo "update $method";
            $attribute->$method($value);
            $this->persist($attribute);
        } else {
            // insert
            echo "insert $method";
            $this->eav = new $this->class($this->poInstance);
            $this->eav->setName($name);
            $this->eav->$method($value);
            $this->poInstance->addEAV($this->eav);
            $this->persist($this->eav);
        }
    }

    private function getValue($name, $type)
    {
        $method = 'get' . $type;
        $attribute = $this->existAttribute($name, $type);
        return $attribute->$method($name);
    }

    public function putString($name, $value)
    {
        $this->setValue($name, $value, EAVBO::$TYPE_STRING);
    }

    public function removeString($name)
    {
        $this->safeDelete($name, EAVBO::$TYPE_STRING);
    }

    public function getString($name)
    {
        return $this->getValue($name, EAVBO::$TYPE_STRING);
    }

    public function putText($name, $value)
    {
        $this->setValue($name, $value, EAVBO::$TYPE_TEXT);
    }

    public function getText($name)
    {
        return $this->getValue($name, EAVBO::$TYPE_TEXT);
    }

    public function removeText($name)
    {
        $this->safeDelete($name, EAVBO::$TYPE_TEXT);
    }

    public function putInteger($name, $value)
    {
        $this->setValue($name, $value, EAVBO::$TYPE_INTEGER);
    }

    public function getInteger($name)
    {
        return $this->getValue($name, EAVBO::$TYPE_INTEGER);
    }

    public function removeInteger($name)
    {
        $this->safeDelete($name, EAVBO::$TYPE_INTEGER);
    }

    public function putDate($name, $value)
    {
        $this->setValue($name, $value, EAVBO::$TYPE_DATE);
    }

    public function getDate($name)
    {
        return $this->getValue($name, EAVBO::$TYPE_DATE);
    }

    public function removeDate($name)
    {
        $this->safeDelete($name, EAVBO::$TYPE_DATE);
    }

    public function putObject($name, $value)
    {
        $this->setValue($name, $value, EAVBO::$TYPE_OBJECT);
    }

    public function getObject($name)
    {
        return $this->getValue($name, EAVBO::$TYPE_OBJECT);
    }

    public function removeObject($name)
    {
        $this->safeDelete($name, EAVBO::$TYPE_OBJECT);
    }


}